package com.lujianfei.tiananyungu

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.app.ActivityCompat
import com.lujianfei.tiananyungu.shopmanager.Restaurant
import com.lujianfei.tiananyungu.shopmanager.ShopDataManager
import com.lujianfei.tiananyungu.ui.theme.TiananyunguTheme
import com.lujianfei.tiananyungu.utils.GpsToBaidu
import com.lujianfei.tiananyungu.utils.SortUtils
import kotlinx.coroutines.flow.flow

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // 设置状态栏颜色
        super.onCreate(savedInstanceState)
        setContent {
            TiananyunguTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Main()
                }
            }
        }
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ),
                0x100
            )
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun Main(modifier: Modifier = Modifier) {
    val filter = remember {
        mutableStateListOf<FilterItem>()
    }
    val list = remember {
        mutableStateListOf<HeadItem>()
    }
    val origin = remember {
        mutableStateListOf<HeadItem>()
    }
    Column(modifier = modifier.fillMaxSize()) {
        FilterLine(filter, list, origin)
        LazyColumn(contentPadding = PaddingValues(bottom = 30.dp)) {
            list.forEach { headItem->
                stickyHeader {
                    Header(headItem)
                }
                items(headItem.list) {
                    Item(it)
                }
            }
        }
    }
    if (origin.isEmpty()) {
        LoadData(list, origin, filter)
    }
}

@Composable
private fun LoadData(
    list: SnapshotStateList<HeadItem>,
    origin: SnapshotStateList<HeadItem>,
    filter: SnapshotStateList<FilterItem>
) {
    LaunchedEffect(key1 = "load") {
        flow {
            emit(ShopDataManager.instance.load())
        }.collect {
            val setType = mutableSetOf<String>()
            val setSubType = mutableMapOf<String,MutableSet<String>>()

            // 用于构建树结构
            val mapBuildingRestaurant = mutableMapOf<String, MutableList<Restaurant>>()
            it.forEach {
                setType.add(it.sub_type)
                it.sub_sub_type?.let {sub_sub_type->
                    if (setSubType.containsKey(it.sub_type)) {
                        setSubType[it.sub_type]?.add(sub_sub_type)
                    } else {
                        setSubType[it.sub_type] = mutableSetOf(sub_sub_type)
                    }
                }
                val buildingKey = "${it.area}${it.building}"
                if (mapBuildingRestaurant.containsKey(buildingKey)) {
                    mapBuildingRestaurant[buildingKey]?.add(it)
                } else {
                    mapBuildingRestaurant[buildingKey] = arrayListOf(it)
                }
            }
            // 对 key （n栋）进行排序
            for (mapitem in mapBuildingRestaurant) {
                val sublist = mutableStateListOf<Restaurant>()
                mapitem.value.forEach {
                    sublist.add(it)
                }
                val sublistOrigin = mutableStateListOf<Restaurant>()
                mapitem.value.forEach {
                    sublistOrigin.add(it)
                }
                sublist.sortWith(SortUtils.SubItemSort())
                sublistOrigin.sortWith(SortUtils.SubItemSort())
                list.add(HeadItem(title = mapitem.key, list = sublist))
                origin.add(HeadItem(title = mapitem.key, list = sublistOrigin))
            }

            list.sortWith(SortUtils.HeadItemSort())
            origin.sortWith(SortUtils.HeadItemSort())

            // 构建筛选树
            if (filter.isEmpty()) {
                // 热门类型
                val subTypeTop = setOf("海鲜","火锅","烤肉", "烤鱼", "蛙肉", "烧烤", "麻辣烫","快餐")

                filter.add(FilterItem(checked = mutableStateOf(true), text = "全部", subItems = mutableStateListOf()))
                for (subType in setType) {
                    // 添加分类
                    val subfilter = mutableStateListOf<FilterItem>()
                    // 父分类
                    val parent = FilterItem(checked = mutableStateOf(false), text = subType, subItems = subfilter)
                    // 添加子分类
                    setSubType[subType]?.forEach {
                        subfilter.add(FilterItem(checked = mutableStateOf(false), text = it, subItems = mutableStateListOf(), parent = parent))
                    }
                    // 按热门类型排序
                    subfilter.sortBy {
                        if (subTypeTop.contains(it.text)) {
                            subTypeTop.indexOf(it.text)
                        } else {
                            subTypeTop.size + 1
                        }
                    }
                    // 尾项【其它】
                    subfilter.find { it.text == "其它" }?.let { subOther->
                        subfilter.remove(subOther)
                        subfilter.add(subOther)
                    }
                    // 新增子项【全部】
                    subfilter.add(0,FilterItem(checked = mutableStateOf(true), text = "全部", subItems = mutableStateListOf(), parent = parent))
                    filter.add(parent)
                }
            }
            findCurrentPos(origin, list)
        }

    }
}

@SuppressLint("MissingPermission")
private fun findCurrentPos(origin: SnapshotStateList<HeadItem>,list: SnapshotStateList<HeadItem>) {
    val mapLocation = mapOf(
        "1期1栋" to CustomLocation(lon_lat = "114.074503,22.664846"),
        "1期2栋" to CustomLocation(lon_lat = "114.076445,22.664829"),
        "1期3栋" to CustomLocation(lon_lat = "114.076151,22.666001"),
        "1期4栋" to CustomLocation(lon_lat = "114.077049,22.666712"),
        "2期4栋" to CustomLocation(lon_lat = "114.073219,22.665023"),
        "2期6栋" to CustomLocation(lon_lat = "114.073889,22.665991"),
        "2期8栋" to CustomLocation(lon_lat = "114.073023,22.666201"),
        "2期10栋" to CustomLocation(lon_lat = "114.071768,22.665069"),
        "2期11栋" to CustomLocation(lon_lat = "114.073219,22.665023"),
    )
    (MyApplication.instance.getSystemService(Context.LOCATION_SERVICE) as LocationManager?)?.let {
        runCatching {
            val location = it.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
            val mySelfBaiduLocation = GpsToBaidu.wgs2bd(lat = location?.latitude?:0.0, lon = location?.longitude?:0.0)
            val locationList = mapLocation.toList()
            locationList.minByOrNull {
                val distance = GpsToBaidu.distance(
                    lat1 = mySelfBaiduLocation[0],
                    lon1 = mySelfBaiduLocation[1],
                    lat2 = it.second.getLat(),
                    lon2 = it.second.getLon()
                )
                Log.d("findCurrentPos", "${it.first} $distance km")
                distance
            }?.let { nearestLocation->
                val distKM = GpsToBaidu.distance(
                    lat1 = mySelfBaiduLocation[0],
                    lon1 = mySelfBaiduLocation[1],
                    lat2 = nearestLocation.second.getLat(),
                    lon2 = nearestLocation.second.getLon()
                )
                if (distKM < 2f) { // 2公里内 算有效
                    val lastNearestLocationKey = nearestLocation.first
                    println("当前位置：${lastNearestLocationKey} ")
                    origin.forEach { it.isHere.value = false }
                    origin.find { listItem->listItem.title == lastNearestLocationKey }?.isHere?.value = true
                    list.forEach { it.isHere.value = false }
                    list.find { listItem->listItem.title == lastNearestLocationKey }?.isHere?.value = true
                }
            }
        }
    }
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun FilterLine(
    filter: SnapshotStateList<FilterItem>,
    list: SnapshotStateList<HeadItem>,
    origin: SnapshotStateList<HeadItem>
) {
    val context = LocalContext.current
    Column {
        Row {
            filter.forEach { filterItem ->
                Row(
                    horizontalArrangement = Arrangement.Center,
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier
                        .weight(1f)
                        .height(40.dp)
                        .clickable {
                            clickOnRadio(filterList = filter, filterItem, list, origin)
                        }
                ) {
                    Text(text = filterItem.text, color = if (filterItem.checked.value) Color.Blue else Color.Black, fontSize = 18.sp)
                    if (filterItem.checked.value) {
                        Icon(Icons.Default.Done, contentDescription = "", tint = Color.Blue)
                    }
                }
            }

            if (filter.isNotEmpty()) {
                Icon(
                    Icons.Outlined.Search,
                    contentDescription = "",
                    Modifier.padding(top = 8.dp).clickable {
                        // 搜索
                        SearchActivity.start(context)
                    })
            }
        }
        // 子菜单
        val filterList = filter.find { it.checked.value }?.subItems
        if (!filterList.isNullOrEmpty()) {
            FlowRow {
                filterList.forEach { filterItem ->
                    Row(
                        horizontalArrangement = Arrangement.Center,
                        modifier = Modifier
                            .padding(start = 0.dp, bottom = 5.dp)
                            .background(
                                color = if (filterItem.checked.value) Color.Gray else Color.White,
                            )
                            .clickable {
                                clickOnSubRadio(filterList = filterList, filterItem, list, origin)
                            },
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(text = filterItem.text, modifier = Modifier.padding(horizontal = 10.dp), fontSize = 18.sp, color = if (filterItem.checked.value) Color.White else Color.Gray)
                    }
                }
            }
        }
    }
}
private fun clickOnRadio(
    filterList: SnapshotStateList<FilterItem>,
    filterItem: FilterItem,
    list: SnapshotStateList<HeadItem>,
    origin: SnapshotStateList<HeadItem>
) {
    filterList.forEach { it.checked.value = false }
    filterItem.checked.value = true

    if (filterItem.text == "全部") {
        list.clear()
        origin.forEach {
            val tmpList = mutableStateListOf<Restaurant>()
            it.list.forEach {
                tmpList.add(it)
            }

            list.add(HeadItem(title = it.title, list = tmpList, isHere = it.isHere))
        }
    } else {
        filterItem.subItems.forEach { it.checked.value = false }
        filterItem.subItems.firstOrNull()?.checked?.value = true
        origin.forEach { originItem ->
            val find = list.find { it.title == originItem.title }
            val subList:SnapshotStateList<Restaurant>?
            if (find == null) {
                subList = mutableStateListOf()
                list.add(HeadItem(title  =originItem.title, list = subList, isHere = originItem.isHere))
            } else {
                subList = find.list
            }
            subList.clear()
            originItem.list.filter { it.sub_type == filterItem.text }.let { filterResult ->
                if (filterResult.isNotEmpty()) {
                    subList.addAll(filterResult)
                }
            }
        }
        // 按栋排序
        list.sortWith(SortUtils.HeadItemSort())
        val itemEmpty = list.filter { it.list.isEmpty() }
        if (itemEmpty.isNotEmpty()) {
            list.removeAll(itemEmpty)
        }
    }
}

private fun clickOnSubRadio(
    filterList: SnapshotStateList<FilterItem>,
    filterItem: FilterItem,
    list: SnapshotStateList<HeadItem>,
    origin: SnapshotStateList<HeadItem>
) {
    filterList.forEach { it.checked.value = false }
    filterItem.checked.value = true

    if (filterItem.text == "全部") {
        origin.forEach { originItem ->
            val find = list.find { it.title == originItem.title }
            val subList:SnapshotStateList<Restaurant>?
            if (find == null) {
                subList = mutableStateListOf()
                list.add(HeadItem(title = originItem.title, list = subList, isHere = originItem.isHere))
            } else {
                subList = find.list
            }
            subList.clear()
            originItem.list.filter { it.sub_type == filterItem.parent?.text }.let { filterResult ->
                if (filterResult.isNotEmpty()) {
                    subList.addAll(filterResult)
                }
            }
        }
        // 按栋排序
        list.sortWith(SortUtils.HeadItemSort())
        val itemEmpty = list.filter { it.list.isEmpty() }
        if (itemEmpty.isNotEmpty()) {
            list.removeAll(itemEmpty)
        }
    } else {
        origin.forEach { originItem ->
            val find = list.find { it.title == originItem.title }
            val subList:SnapshotStateList<Restaurant>?
            if (find == null) {
                subList = mutableStateListOf()
                list.add(HeadItem(title = originItem.title, list = subList, isHere = originItem.isHere))
            } else {
                subList = find.list
            }
            subList.clear()
            originItem.list.filter { it.sub_type == filterItem.parent?.text && it.sub_sub_type == filterItem.text }.let { filterResult ->
                if (filterResult.isNotEmpty()) {
                    subList.addAll(filterResult)
                }
            }
        }
        // 按栋排序
        list.sortWith(SortUtils.HeadItemSort())
        val itemEmpty = list.filter { it.list.isEmpty() }
        if (itemEmpty.isNotEmpty()) {
            list.removeAll(itemEmpty)
        }
    }
}

@Composable
fun Header(headItem: HeadItem) {
    Box(
        Modifier
            .fillMaxWidth()
            .height(40.dp)
            .background(color = Color.Gray)) {
        Row(modifier = Modifier
            .align(Alignment.CenterStart)
            .padding(start = 15.dp)) {
            Text(text = headItem.title, fontSize = 20.sp, color = Color.White)
            if (headItem.isHere.value) {
                Text(text = "(当前位置)", fontSize = 20.sp, color = Color.Yellow, modifier = Modifier.padding(start = 10.dp))
            }
        }
    }
}

@Composable
private fun Item(it: Restaurant) {
    Box(
        Modifier
            .fillMaxWidth()
            .defaultMinSize(minHeight = 20.dp)) {
        Row(modifier = Modifier
            .align(Alignment.CenterStart)
            .padding(horizontal = 15.dp)
            .fillMaxWidth()
        ) {
            Text(text = "${it.name}" , fontSize = 20.sp, modifier = Modifier.weight(1f))
            Text(text = "${it.block}${it.floor}" , fontSize = 20.sp, textAlign = TextAlign.End)
        }
    }
}

data class FilterItem(val checked: MutableState<Boolean>, val text:String, val parent:FilterItem?= null, val subItems:SnapshotStateList<FilterItem>)
data class HeadItem(val title:String, val isHere:MutableState<Boolean> = mutableStateOf(false), val list: SnapshotStateList<Restaurant>)

data class CustomLocation(val lon_lat:String = "114.074503,22.664846") {
    fun getLon():Double {
        return lon_lat.split(",")[0].toDouble()
    }

    fun getLat():Double  {
        return lon_lat.split(",")[1].toDouble()
    }
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    TiananyunguTheme {
        Main()
    }
}